#! /usr/bin/python


'''

This class accepts a CodeTree, and generates a python class based off
of it. First, I'll make it generate a static .py file. Afterwards, I 
will give it a method to generate the class on the fly :P

@author kllvql
@date 12/23/11

'''

from ProjectFlags import *

TEST  = False
DEBUG = False

TEST  = TEST  or TEST_ALL
DEBUG = DEBUG or DEBUG_ALL

from CodeTree import GETTERS, SETTERS

class CodeTreeToPython:
	'''
	Accepts a codeTree in it's constructor, and turns it into a string
	representation of a Python Class capable of being outputted to a
	file and ran. 
	'''

	
	def __init__(self, codeTree):
		self.codeTree = codeTree
	
	
	def __str__(self):
		'''
		This is where the heavy lifting is done. The actual python 
		class is obtained from this class through the str() method.
		'''
		name = self.codeTree.name()
		fields = self.codeTree.fields()
		flags = self.codeTree.flags()
		methods = self.codeTree.methods()
		
		returned = self._declaration(name) + '\n'
		returned += self._init(fields) + '\n'
		if GETTERS in flags:
			returned += self._getters(fields) + '\n'
		if SETTERS in flags:
			returned += self._setters(fields) + '\n'
		returned += self._methods(methods) + '\n'
		
		return returned
	
	def _declaration(self, name):
		'''
		Returns the class declaration as a string
		'''
		return 'class ' + name + ':\n'
	
	def _init(self, fields):
		'''
		Returns the init method as a string
		'''
		returned = '\tdef __init__(self'
		for field in fields:
			returned += ', ' + field.getName()
		returned += '):\n'
		for field in fields:
			returned += '\t\tself.' + field.getName() + \
						' = ' + field.getName() + '\n'
		return returned
		
	def _getters(self, fields):
		'''
		Returns the getters for all the fields as a string
		'''
		returned = ''
		for field in fields:
			returned += self._getter(field)
		return returned
	
	def _setters(self, fields):
		'''
		Returns the setters for all the fields as a string
		'''
		returned = ''
		for field in fields:
			returned += self._setter(field)
		return returned
	
	def _getter(self, field):
		'''
		Returns a getter for a single field as a string
		'''
		name = field.getName()
		returned = '\tdef get' + self._rSenCap(name) + \
				   '(self):\n'
		returned += '\t\treturn self.' + name + '\n'
		return returned
		
	def _setter(self, field):
		'''
		Returns a setter for a single field
		'''
		name = field.getName()
		returned = '\tdef set' +  self._rSenCap(name) + \
				   '(self, ' + name + '):\n'
		returned += '\t\tself.' + name + ' = ' + name + '\n'
		return returned

	def _methods(self, methods):
		'''
		Returns a string representation of all the methods in the
		class.
		'''
		returned = ''
		for method in methods:
			returned +=  self._method(method)
		return returned
	
	def _method(self, method):
		'''
		Returns a string representation for a singluar method in this 
		class
		'''
		name = method.getName()
		args = method.args()
		body = method.body()
		
		returned = '\tdef ' + name + '('
		for arg in args:
			returned += arg + ', '
		
		if len(args) >= 1: # Remove the extra ', '
			returned = returned[:-2]
		returned += '):\n'
		
		if len(body) > 0:
			for line in body:
				returned += '\t\t' + line.getName() + '\n'
		else:
			returned += '\t\tpass\n\n'
		
		return returned

	def _rSenCap(string):
		'''
		Returns a reverse sentence capitalization for a string.
		'''
		return string[0].upper() + string[1:]
	_rSenCap = staticmethod(_rSenCap)
	
		
def test():
	print "CodeTreeToPython.py testing..."
	
	from SExpressionToCodeTree import SExpressionToCodeTree as sExTCT
	from SExpression import SExpression as SExp
	ch = '(Character (flag getters) (flag setters) ' + \
		 '(field (age (type int))) (name (type string)))'
	ct = sExTCT(SExp(ch)).getCodeTree()
	print str(ct)
	ctTP = CodeTreeToPython(ct)
	print str(ctTP)
	
	print "End CodeTreeToPython.py testing.\n"
	

if __name__ == '__main__' or TEST:
	test()
		
		


		
		
